#ifndef _RENZO_VERTEX_BUFFER_
#define _RENZO_VERTEX_BUFFER_

#include "RenzoMustHave.h"
#include "RenzoVertex.h"	// explicitly include so that std::vector<Vertex> can be declared (need the sizeof(Vertex)). 
							// In RenzoMustHave, only forward declaration class Vertex, so sizeof(Vertex) is unknown.
#include "RenzoFace.h"

namespace Renzo
{
/*
@description
VertexBuffer contains all geometry information necessary for RenderBuffer to rasterize/ray trace.

@log
2009-09-28: support triangle list. Other types later.
*/
class RENZODERER_API VertexBuffer
{
public:
	VertexBuffer(void);
	virtual ~VertexBuffer(void);

	/**
	Cache input geometry
	*/
	virtual void clear();
	virtual void add(Vertex* v);
	virtual void add(Face* f);
	virtual void add(Mesh* m);
	virtual void add(int unit, Texture* tex);
	/**
	Transfer geometry information to graphic hardware memory
	*/
	virtual void copyToHardware() = 0;

	/**
	Draw the geometry 
	*/
	virtual void render() = 0;

protected:
	typedef std::vector<Vertex> VertexList;
	VertexList vertices;
	typedef std::vector<Index> IndexList;
	IndexList indices;
	int nbTriangles;
	// TODO: extendable to multiple texcoords (texcoords1, texcoords2...). The same for textures1, textures2
	//typedef std::vector<TexCoord> TexCoordList;
	//TexCoordList texcoords;
	typedef std::vector<Texture*> TextureList;
	TextureList textures;

	/*
	 Capture the start position of an object in vertex list and index list
	 */
	struct ObjectOffset {
		//unsigned short vertexOffset;
		Range vertexOffset;
		Range indexOffset;
		//unsigned short indexOffset;
		//unsigned short texcoordOffset; // each vertex has 1 texcoord
		Range textureOffset; // maximum 8 textures per object. Index on 

		SceneNode* node;
	};	
	typedef std::vector<ObjectOffset> ObjectOffsetList;	// keep track of the number of objects and its offsets in the vertex buffer
	ObjectOffsetList objectOffsets;
public:
	//void appendObject();	// append new object to vertex buffer. Called when the sceneNodeMesh calls the copyToHardware(matTransform)
	void beginObject();		// start a new object
	void endObject();		// complete adding a new object
	void beginTexture();
	void endTexture();
protected:
	TouchState state;		// keep track of the state to see if the vertices are updated (which means we need to copy to hardware again)
};
}

#endif
